#pragma once
#include <YSimpleNetwork/IUDPSession.h>
#include <YSimpleNetwork/YMessageBlock.h>
#include <YSimpleNetwork/YProactorTokenOnRecvFrom.h>
#include <YSimpleNetwork/YProactorTokenOnSendTo.h>
#include <atomic>


namespace ysimple_system
{
	struct IProactor;
}


namespace ysimple_network
{
	#define RELEASE_UDP_SESSION_FUNCTOR	RELEASE_FUNCTOR(IUDPSession)	
	class YUdpSession :
		public IUDPSession
	{
		ysimple_system::IProactor&	m_proactor;
		bool	m_reused;
		SOCKET	m_socket;
		YMessageBlock					m_messageBlock;
		RELEASE_UDP_SESSION_FUNCTOR				m_releaseFunctor;
		bool	m_disconnected;
		
	protected:
		YProactorTokenOnRecvFrom		m_recvFromToken;
		ysimple_system::IProactor&	getProactor();
	public:
		YUdpSession(ysimple_system::IProactor& proactor, SOCKET socket, bool reusedSocket, RELEASE_UDP_SESSION_FUNCTOR releaseFunctor);
		virtual ~YUdpSession(void);

		bool				init() override;
		bool				bind(const YEndPoint& endPoint) override;
		SOCKET			getSocket() const override;
		bool				sendto(const YEndPoint& toEndPoint, PACKET_SPTR packet, ISendToCallback& callback) override;
		bool				recvfrom(IRecvFromCallback& callback) override;
		void				shutdown() override;
		void				close() override;

	private:
		std::atomic<int>			m_refCount;
	public:
		void				release() override;
		void				addRef() override;
	};

}

